package org.lw;

import org.apache.commons.codec.binary.Base64;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RsaUtil {

    /**
     * 签名
     * @param preStr 待签名字符串
     * @param privateKeyPKCS8 私钥字符串PKCS8格式
     * @return base64字符串
     * @throws Exception
     */
    public static String getSign(String preStr, String privateKeyPKCS8)
            throws Exception {

        privateKeyPKCS8 = privateKeyPKCS8.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replace("\r", "").replace("\n", "").trim();

        String strSign = "";
        String suite = "SHA256WithRSA";

        //初始化算法SHA256
        Signature   signature = Signature.getInstance(suite);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyPKCS8));
        //初始化私钥+RSA
        KeyFactory keyFac = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFac.generatePrivate(keySpec);
        signature.initSign(privateKey);

        //待签名字符串转byte数组使用UTF8
        byte[] msgBuf = preStr.getBytes("UTF8");
        signature.update(msgBuf);
        byte[] byteSign = signature.sign();
        //签名值byte数组转字符串用BASE64
        strSign = Base64.encodeBase64String(byteSign);
        return strSign;

    }

    /**
     * 验证签名
     * @param preStr 待验证签名字符串
     * @param publicKeyStr 公钥字符串
     * @param rspSign 待验证签名值
     * @return 是否
     * @throws Exception
     */
    public static boolean verifySign(String preStr, String publicKeyStr, String rspSign)
            throws Exception {

        publicKeyStr = publicKeyStr.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace("\r", "").replace("\n", "").trim();
        //待验证签名值base64解码
        byte[] sign = Base64.decodeBase64(rspSign);
        String suite = "SHA256WithRSA";

        //初始化算法SHA256
        Signature  signature = Signature.getInstance(suite);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
        //初始化公钥+RSA
        KeyFactory keyFac = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFac.generatePublic(keySpec);
        signature.initVerify(pubKey);

        //待签名字符串转byte数组使用UTF8
        byte[] msgBuf = preStr.getBytes("UTF8");
        signature.update(msgBuf);
        boolean bRst = signature.verify(sign);
        return bRst;
    }


}
